#include <bits/stdc++.h>

const int MAXN = 300005;

using namespace std;

struct Edge {
	int to, nxt, w;
} E[MAXN << 1];

int H[MAXN], tot;

inline void Add_Edge (const int u, const int v) {
	E[++ tot] = {v, H[u], 1}, H[u] = tot;
	E[++ tot] = {u, H[v], 1}, H[v] = tot;
}

int Dis[MAXN];
bool Vis[MAXN];

struct Node {
	int u, dis;
	
	inline bool operator < (const Node &a) const {
		return dis > a.dis;
	}
};

inline void Dijkstra (const int x) {
	memset (Dis, 63, sizeof Dis);
	memset (Vis, 0 , sizeof Vis);
	
	priority_queue <Node> Q;
	Q.push ({x, 0}), Dis[x] = 0;
	
	int u;
	
	while (!Q.empty ()) {
		u = Q.top ().u, Q.pop ();
		if (Vis[u]) continue ;
		Vis[u] = 1;
		for (int i = H[u]; i; i = E[i].nxt)
			if (Dis[E[i].to] > Dis[u] + E[i].w) 
				Dis[E[i].to] = Dis[u] + E[i].w, Q.push ({E[i].to, Dis[E[i].to]});
	}
}

int N, M, A, B;
int u, v;

int main () {
	
	freopen ("edge.in", "r", stdin);
	freopen ("edge.out", "w", stdout);
	
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	cin >> N >> M >> A >> B;
	
	for (int i = 1; i <= M; ++ i)
		cin >> u >> v, Add_Edge (u, v);
	
	Dijkstra (1);
	
	for (int i = 2; i <= N; ++ i) {
	//	cerr << Dis[i] << '\n';
		if ((A << 1) < B) cout << 1ll * Dis[i] * A << '\n';
		if ((A << 1) > B && A < B) cout << 1ll * (Dis[i] >> 1) * B + 1ll * (Dis[i] & 1) * A << '\n';
	}
	
	return 0;
}
